home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2005 October / PCWOCT05.iso / Software / FromTheMag / XAMPP 1.4.14 / xampp-win32-1.4.14-installer.exe / xampp / php / pear / Auth / Container / DB.php next >
PHP Script  |  2004-03-24  |  13KB  |  410 lines

  1. <?php
  2. //
  3. // +----------------------------------------------------------------------+
  4. // | PHP Version 4                                                        |
  5. // +----------------------------------------------------------------------+
  6. // |                                                                      |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 2.02 of the PHP license,      |
  9. // | that is bundled with this package in the file LICENSE, and is        |
  10. // | available at through the world-wide-web at                           |
  11. // | http://www.php.net/license/2_02.txt.                                 |
  12. // | If you did not receive a copy of the PHP license and are unable to   |
  13. // | obtain it through the world-wide-web, please send a note to          |
  14. // | license@php.net so we can mail you a copy immediately.               |
  15. // +----------------------------------------------------------------------+
  16. // | Authors: Martin Jansen <mj@php.net>                                  |
  17. // +----------------------------------------------------------------------+
  18. //
  19. // $Id: DB.php,v 1.40 2003/11/15 13:37:26 yavo Exp $
  20. //
  21.  
  22. require_once 'Auth/Container.php';
  23. require_once 'DB.php';
  24.  
  25. /**
  26.  * Storage driver for fetching login data from a database
  27.  *
  28.  * This storage driver can use all databases which are supported
  29.  * by the PEAR DB abstraction layer to fetch login data.
  30.  *
  31.  * @author   Martin Jansen <mj@php.net>
  32.  * @package  Auth
  33.  * @version  $Revision: 1.40 $
  34.  */
  35. class Auth_Container_DB extends Auth_Container
  36. {
  37.  
  38.     /**
  39.      * Additional options for the storage container
  40.      * @var array
  41.      */
  42.     var $options = array();
  43.  
  44.     /**
  45.      * DB object
  46.      * @var object
  47.      */
  48.     var $db = null;
  49.     var $dsn = '';
  50.  
  51.     /**
  52.      * User that is currently selected from the DB.
  53.      * @var string
  54.      */
  55.     var $activeUser = '';
  56.  
  57.     // {{{ Constructor
  58.  
  59.     /**
  60.      * Constructor of the container class
  61.      *
  62.      * Initate connection to the database via PEAR::DB
  63.      *
  64.      * @param  string Connection data or DB object
  65.      * @return object Returns an error object if something went wrong
  66.      */
  67.     function Auth_Container_DB($dsn)
  68.     {
  69.         $this->_setDefaults();
  70.  
  71.         if (is_array($dsn)) {
  72.             $this->_parseOptions($dsn);
  73.  
  74.             if (empty($this->options['dsn'])) {
  75.                 PEAR::raiseError('No connection parameters specified!');
  76.             }
  77.         } else {
  78.             $this->options['dsn'] = $dsn;
  79.         }
  80.     }
  81.  
  82.     // }}}
  83.     // {{{ _connect()
  84.  
  85.     /**
  86.      * Connect to database by using the given DSN string
  87.      *
  88.      * @access private
  89.      * @param  string DSN string
  90.      * @return mixed  Object on error, otherwise bool
  91.      */
  92.     function _connect($dsn)
  93.     {
  94.         if (is_string($dsn) || is_array($dsn)) {
  95.             $this->db = DB::Connect($dsn);
  96.         } elseif (get_parent_class($dsn) == "db_common") {
  97.             $this->db = $dsn;
  98.         } elseif (DB::isError($dsn)) {
  99.             return PEAR::raiseError($dsn->getMessage(), $dsn->getCode());
  100.         } else {
  101.             return PEAR::raiseError('The given dsn was not valid in file ' . __FILE__ . ' at line ' . __LINE__,
  102.                                     41,
  103.                                     PEAR_ERROR_RETURN,
  104.                                     null,
  105.                                     null
  106.                                     );
  107.         }
  108.  
  109.         if (DB::isError($this->db) || PEAR::isError($this->db)) {
  110.             return PEAR::raiseError($this->db->getMessage(), $this->db->getCode());
  111.         } else {
  112.             return true;
  113.         }
  114.     }
  115.  
  116.     // }}}
  117.     // {{{ _prepare()
  118.  
  119.     /**
  120.      * Prepare database connection
  121.      *
  122.      * This function checks if we have already opened a connection to
  123.      * the database. If that's not the case, a new connection is opened.
  124.      *
  125.      * @access private
  126.      * @return mixed True or a DB error object.
  127.      */
  128.     function _prepare()
  129.     {
  130.         if (!DB::isConnection($this->db)) {
  131.             $res = $this->_connect($this->options['dsn']);
  132.             if(DB::isError($res) || PEAR::isError($res)){
  133.                 return $res;
  134.             }
  135.         }
  136.         return true;
  137.     }
  138.  
  139.     // }}}
  140.     // {{{ query()
  141.  
  142.     /**
  143.      * Prepare query to the database
  144.      *
  145.      * This function checks if we have already opened a connection to
  146.      * the database. If that's not the case, a new connection is opened.
  147.      * After that the query is passed to the database.
  148.      *
  149.      * @access public
  150.      * @param  string Query string
  151.      * @return mixed  a DB_result object or DB_OK on success, a DB
  152.      *                or PEAR error on failure
  153.      */
  154.     function query($query)
  155.     {
  156.         $err = $this->_prepare();
  157.         if ($err !== true) {
  158.             return $err;
  159.         }
  160.         return $this->db->query($query);
  161.     }
  162.  
  163.     // }}}
  164.     // {{{ _setDefaults()
  165.  
  166.     /**
  167.      * Set some default options
  168.      *
  169.      * @access private
  170.      * @return void
  171.      */
  172.     function _setDefaults()
  173.     {
  174.         $this->options['table']       = 'auth';
  175.         $this->options['usernamecol'] = 'username';
  176.         $this->options['passwordcol'] = 'password';
  177.         $this->options['dsn']         = '';
  178.         $this->options['db_fields']   = '';
  179.         $this->options['cryptType']   = 'md5';
  180.     }
  181.  
  182.     // }}}
  183.     // {{{ _parseOptions()
  184.  
  185.     /**
  186.      * Parse options passed to the container class
  187.      *
  188.      * @access private
  189.      * @param  array
  190.      */
  191.     function _parseOptions($array)
  192.     {
  193.         foreach ($array as $key => $value) {
  194.             if (isset($this->options[$key])) {
  195.                 $this->options[$key] = $value;
  196.             }
  197.         }
  198.  
  199.         /* Include additional fields if they exist */
  200.         if(!empty($this->options['db_fields'])){
  201.             if(is_array($this->options['db_fields'])){
  202.                 $this->options['db_fields'] = join($this->options['db_fields'], ', ');
  203.             }
  204.             $this->options['db_fields'] = ', '.$this->options['db_fields'];
  205.         }
  206.     }
  207.  
  208.     // }}}
  209.     // {{{ fetchData()
  210.  
  211.     /**
  212.      * Get user information from database
  213.      *
  214.      * This function uses the given username to fetch
  215.      * the corresponding login data from the database
  216.      * table. If an account that matches the passed username
  217.      * and password is found, the function returns true.
  218.      * Otherwise it returns false.
  219.      *
  220.      * @param   string Username
  221.      * @param   string Password
  222.      * @return  mixed  Error object or boolean
  223.      */
  224.     function fetchData($username, $password)
  225.     {
  226.         // Prepare for a database query
  227.         $err = $this->_prepare();
  228.         if ($err !== true) {
  229.             return PEAR::raiseError($err->getMessage(), $err->getCode());
  230.         }
  231.  
  232.         // Find if db_fileds contains a *, i so assume all col are selected
  233.         if(strstr($this->options['db_fields'], '*')){
  234.             $sql_from = "*";
  235.         }
  236.         else{
  237.             $sql_from = $this->options['usernamecol'] . ", ".$this->options['passwordcol'].$this->options['db_fields'];
  238.         }
  239.         /**
  240.          Old Style, removed to go around the oci8 
  241.          problem 
  242.          See bug 206
  243.          http://pear.php.net/bugs/bug.php?id=206
  244.          
  245.         $query = "SELECT ! FROM ! WHERE ! = ?";
  246.         $query_params = array(
  247.                          $sql_from,
  248.                          $this->options['table'],
  249.                          $this->options['usernamecol'],
  250.                          $username
  251.                          );
  252.         */
  253.         
  254.         $query = "SELECT ".$sql_from.
  255.                 " FROM ".$this->options['table'].
  256.                 " WHERE ".$this->options['usernamecol']." = '".$this->db->quoteString($username)."'";
  257.         
  258.         $res = $this->db->getRow($query, null, DB_FETCHMODE_ASSOC);
  259.  
  260.         if (DB::isError($res)) {
  261.             return PEAR::raiseError($res->getMessage(), $res->getCode());
  262.         }
  263.         if (!is_array($res)) {
  264.             $this->activeUser = '';
  265.             return false;
  266.         }
  267.         if ($this->verifyPassword(trim($password, "\r\n"),
  268.                                   trim($res[$this->options['passwordcol']], "\r\n"),
  269.                                   $this->options['cryptType'])) {
  270.             // Store additional field values in the session
  271.             foreach ($res as $key => $value) {
  272.                 if ($key == $this->options['passwordcol'] ||
  273.                     $key == $this->options['usernamecol']) {
  274.                     continue;
  275.                 }
  276.                 // Use reference to the auth object if exists
  277.                 // This is because the auth session variable can change so a static call to setAuthData does not make sence
  278.                 if(is_object($this->_auth_obj)){
  279.                     $this->_auth_obj->setAuthData($key, $value);
  280.                 } else {
  281.                     Auth::setAuthData($key, $value);
  282.                 }
  283.             }
  284.  
  285.             return true;
  286.         }
  287.  
  288.         $this->activeUser = $res[$this->options['usernamecol']];
  289.         return false;
  290.     }
  291.  
  292.     // }}}
  293.     // {{{ listUsers()
  294.  
  295.     function listUsers()
  296.     {
  297.         $err = $this->_prepare();
  298.         if ($err !== true) {
  299.             return PEAR::raiseError($err->getMessage(), $err->getCode());
  300.         }
  301.  
  302.         $retVal = array();
  303.  
  304.         // Find if db_fileds contains a *, i so assume all col are selected
  305.         if(strstr($this->options['db_fields'], '*')){
  306.             $sql_from = "*";
  307.         }
  308.         else{
  309.             $sql_from = $this->options['usernamecol'] . ", ".$this->options['passwordcol'].$this->options['db_fields'];
  310.         }
  311.  
  312.         $query = sprintf("SELECT %s FROM %s",
  313.                          $sql_from,
  314.                          $this->options['table']
  315.                          );
  316.         $res = $this->db->getAll($query, null, DB_FETCHMODE_ASSOC);
  317.  
  318.         if (DB::isError($res)) {
  319.             return PEAR::raiseError($res->getMessage(), $res->getCode());
  320.         } else {
  321.             foreach ($res as $user) {
  322.                 $user['username'] = $user[$this->options['usernamecol']];
  323.                 $retVal[] = $user;
  324.             }
  325.         }
  326.         return $retVal;
  327.     }
  328.  
  329.     // }}}
  330.     // {{{ addUser()
  331.  
  332.     /**
  333.      * Add user to the storage container
  334.      *
  335.      * @access public
  336.      * @param  string Username
  337.      * @param  string Password
  338.      * @param  mixed  Additional information that are stored in the DB
  339.      *
  340.      * @return mixed True on success, otherwise error object
  341.      */
  342.     function addUser($username, $password, $additional = "")
  343.     {
  344.         if (function_exists($this->options['cryptType'])) {
  345.             $cryptFunction = $this->options['cryptType'];
  346.         } else {
  347.             $cryptFunction = 'md5';
  348.         }
  349.  
  350.         $additional_key   = '';
  351.         $additional_value = '';
  352.  
  353.         if (is_array($additional)) {
  354.             foreach ($additional as $key => $value) {
  355.                 $additional_key .= ', ' . $key;
  356.                 $additional_value .= ", '" . $value . "'";
  357.             }
  358.         }
  359.  
  360.         $query = sprintf("INSERT INTO %s (%s, %s%s) VALUES ('%s', '%s'%s)",
  361.                          $this->options['table'],
  362.                          $this->options['usernamecol'],
  363.                          $this->options['passwordcol'],
  364.                          $additional_key,
  365.                          $username,
  366.                          $cryptFunction($password),
  367.                          $additional_value
  368.                          );
  369.  
  370.         $res = $this->query($query);
  371.  
  372.         if (DB::isError($res)) {
  373.            return PEAR::raiseError($res->getMessage(), $res->getCode());
  374.         } else {
  375.           return true;
  376.         }
  377.     }
  378.  
  379.     // }}}
  380.     // {{{ removeUser()
  381.  
  382.     /**
  383.      * Remove user from the storage container
  384.      *
  385.      * @access public
  386.      * @param  string Username
  387.      *
  388.      * @return mixed True on success, otherwise error object
  389.      */
  390.     function removeUser($username)
  391.     {
  392.         $query = sprintf("DELETE FROM %s WHERE %s = '%s'",
  393.                          $this->options['table'],
  394.                          $this->options['usernamecol'],
  395.                          $username
  396.                          );
  397.  
  398.         $res = $this->query($query);
  399.  
  400.         if (DB::isError($res)) {
  401.            return PEAR::raiseError($res->getMessage(), $res->getCode());
  402.         } else {
  403.           return true;
  404.         }
  405.     }
  406.  
  407.     // }}}
  408. }
  409. ?>
  410.